/*
 * @Author: yangzonglong
 * @Date: 2021-03-17 11:28:36
 * @version: v1.0.0
 * @Descripttion: reducer
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2021-08-15 15:19:45
 * @Auditor:
 */
import update from 'immutability-helper';
import { FdReducerProps, ActionProps } from './interface';
import { controlToTree, flatControl } from './util';

export const ActionTypes = {
  SYNC_LIST: '@FD/syncList',
  TOGGLE_MENUS: '@FD/toggleMenus',
  CHANGE_CONTROL: '@FD/changeControl',
  SYNC_CUR_CONTROL: '@FD/syncCurControl',
  CHANGE_PREVIEW: '@FD/changePreview',
  CHANGE_TABLECURRENT: '@FD/changeTableCurrent',
  CHANGE_DATALISTCURRENT: '@FD/changeDataListCurrent',
};

export const initialState = {
  list: [],
  hoverControlId: '', // 拖动时正在hover控件id
  dragDirection: '', // 拖动方向
  dragSource: '', // 拖动源 从左侧菜单拖入或画布内拖动排序
  formName: '',
  formDesc: '',
  hideMenus: false,
  preview: false, // 预览模式
  noFormNameDesc: true,
  tableCurrentController: {},
  dataListCurrentController: {}
};

const reducer = (state: FdReducerProps, action: ActionProps): FdReducerProps => {
  const index = state.list.findIndex((item) => item.id === action.curControl?.id);

  switch (action.type) {
    case ActionTypes.SYNC_LIST:
      return {
        ...state,
        list: action.list || [],
        modelListAndModelName: action.modelListAndModelName || '',
        curControl: action.curControl || state.curControl,
      };

    case ActionTypes.CHANGE_CONTROL:
      return {
        ...state,
        curControl: action.curControl,
      };

    case ActionTypes.SYNC_CUR_CONTROL:
      // 变更子组件
      if (action.curControl?.parentId) {
        const flatList = flatControl(state.list);

        flatList.forEach((item, index) => {
          if (item.id === action.curControl?.id) {
            flatList[index] = action.curControl;
          }
        });

        return {
          ...state,
          curControl: action.curControl,
          list: controlToTree(flatList)
        };
      }

      return {
        ...state,
        curControl: action.curControl,
        list: update(state.list, {
          [index]: { $set: action.curControl as any },
        }),
      };

    case ActionTypes.CHANGE_TABLECURRENT:
      return {
        ...state,
        tableCurrentController: action.curColumn,
      };

    case ActionTypes.CHANGE_DATALISTCURRENT:
      return {
        ...state,
        dataListCurrentController: action.curColumn,
      };

    case ActionTypes.TOGGLE_MENUS:
      return {
        ...state,
        hideMenus: action.hideMenus,
      };


    default:
      delete action.type;
      return { ...state, ...action };
  }
};

export default reducer;
